package net.qiqbframework.spring.messaging;

import lombok.extern.slf4j.Slf4j;
import net.qiqbframework.common.Assert;
import net.qiqbframework.common.transaction.Transaction;
import net.qiqbframework.common.transaction.TransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Nonnull;

/**
 * 由 spring 来接管事物
 */
@Slf4j
public class SpringTransactionManager implements TransactionManager {

    private final PlatformTransactionManager transactionManager;
    private final TransactionDefinition transactionDefinition;


    public SpringTransactionManager(PlatformTransactionManager transactionManager,
                                    TransactionDefinition transactionDefinition) {
        Assert.notNull(transactionManager, () -> "transactionManager may not be null");
        this.transactionManager = transactionManager;
        this.transactionDefinition = transactionDefinition;
    }

    public SpringTransactionManager(PlatformTransactionManager transactionManager) {
        this(transactionManager, getDefaultTransactionDefinition());
    }

    private static TransactionDefinition getDefaultTransactionDefinition() {
        final DefaultTransactionDefinition defaultTransactionDefinition = new DefaultTransactionDefinition();
        // 设置传播行为，默认总创建一个新事物
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        defaultTransactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
        return defaultTransactionDefinition;
    }

    @Nonnull
    @Override
    public Transaction startTransaction() {
        TransactionStatus status = transactionManager.getTransaction(transactionDefinition);
        //log.info("开启事物 startTransaction" + status);
        return new Transaction() {
            @Override
            public void commit() {
                commitTransaction(status);
               // log.info("提交事物 commit " + status);
            }

            @Override
            public void rollback() {
                rollbackTransaction(status);
            }
        };
    }


    protected void commitTransaction(TransactionStatus status) {
        if (status.isNewTransaction() && !status.isCompleted()) {
            transactionManager.commit(status);

        }
    }

    protected void rollbackTransaction(TransactionStatus status) {
        if (status.isNewTransaction() && !status.isCompleted()) {
            transactionManager.rollback(status);
        }
    }
}
